package cn.biplam.back.services.log;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import cn.biplam.common.client.Log.Log_Level;
import cn.biplam.common.interfaces.LogServer;
import cn.biplam.common.paramters.SysName;
import cn.biplam.common.tools.TOOLS;
import cn.biplam.common.wrapper.Date;
import cn.biplam.common.wrapper.ErrorMessage;

/**
 * Log日志记录接口实现类
 * @author 	WangSong
 * @create 	2009-3-10 上午09:34:39
 * @version 1.0
 */
public class LogServerImpl extends UnicastRemoteObject implements LogServer{

	private static final long serialVersionUID = -6098482560841106362L;
	private Lock mLock=new ReentrantLock();
	private int iCount=0;
	private static String sLogMode ;

	/**
	 * 构造方法
	 * @throws RemoteException
	 * @throws ErrorMessage 
	 */
	public LogServerImpl() throws RemoteException, ErrorMessage {
		//从系统配置信息中取 日志模式
		if(sLogMode==null){
			sLogMode = TOOLS.getValueByPropertyName(SysName.PropertiesPath, "LOG.RunModel");
		}
	}

	/**
	 * 写日志信息
	 * @param mErrorMessage 日志信息
	 * @param level   日志级别
	 * @throws ErrorMessage  
	 */
	public void write(ErrorMessage mErrorMessage,Log_Level level) throws ErrorMessage {
		addCount();
		StringBuffer sb = new StringBuffer();
		try{
			/**拼接异常日志的说明部分*/
			sb.append(this.getPrompt(level));
			sb.append(new Date().getDateTime("yyyy-MM-dd HH:mm:ss"));
			sb.append(",");
			if(mErrorMessage.getUserID()!=null){
				sb.append("UserID:");
				sb.append(mErrorMessage.getUserID());
				sb.append(",");
			}
			if(mErrorMessage.getPageID()!=null){
				sb.append("PageID:");
				sb.append(mErrorMessage.getPageID());
				sb.append(",");
			}
			sb.append(" ");
			writeByMode(sb.toString(),mErrorMessage);
		}catch(ErrorMessage e){
			throw e;
		}catch(Exception e){
			throw new ErrorMessage(e);
		}finally{
			reduceCount();
		}	
	}

	/**
	 * 写调试日志信息
	 * @param sMessage  日志信息
	 * @throws RemoteException
	 * @throws ErrorMessage 
	 */
	public void write(String sMessage) throws RemoteException, ErrorMessage {
		this.write(sMessage, Log_Level.Debug);
	}

	/**
	 * 写日志信息
	 * @param sMessage  日志信息
	 * @param iLevel    日志级别
	 * @param bUseDefualtMode  是否使用默认模式
	 * @throws RemoteException
	 * @throws ErrorMessage 
	 */
	public void write(String sMessage,Log_Level level) throws RemoteException, ErrorMessage{
		this.write(new ErrorMessage(sMessage), level);
	}

	/**
	 * 根据模式写日志
	 * @param sMode   日志模式 1console 2file 3Database   组合 12，13，23，123
	 * @param sMessage 提示信息
	 * @param mLogMessage 异常信息
	 * @throws ErrorMessage 
	 */
	private void writeByMode(String sMessage,ErrorMessage mErrorMessage) throws ErrorMessage{

		Thread console = new Thread(new LogConsole(sMessage,mErrorMessage));
		Thread file = new Thread(new LogFile(sMessage,mErrorMessage));
		Thread database = new Thread(new LogDatabase(sMessage+mErrorMessage.toString()));

		int iMode = -1;
		if(TOOLS.isNumeric(sLogMode)){
			iMode = TOOLS.stringToInt(sLogMode);
		}else{
			try {
				throw new Exception("【error:】log mode error");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		switch(iMode){
		case 1:
			console.start();
			break;
		case 2:
			file.start();
			break;
		case 3:
			database.start();
			break;
		case 12:
			console.start();
			file.start();
			break;
		case 13:
			console.start();
			database.start();
			break;
		case 23:
			file.start();
			database.start();
			break;
		case 123:
			console.start();
			file.start();
			database.start();
			break;

		}
	}

	/**
	 * 根据日志级别取日志提示部分
	 * @param 	level  日志级别
	 * @return	日志提示
	 */
	private String getPrompt(Log_Level level){
		String prompt = null;
		switch(level){
		case Debug:
			prompt = "【Develop Info】";
			break;
		case Develop_Info:
			prompt = "【Debug】";
			break;
		case Info:
			prompt = "【Info】";
			break;
		case Warnning:
			prompt = "【Warnning】";
			break;
		case Error:
			prompt = "【Error】";
			break;
		case Core_Error:
			prompt = "【System Error】";
			break;
		default:prompt = "【】";
		}
		return prompt;
	}

	/**
	 * 取当前运行的实例个数
	 */
	public int getCount() throws RemoteException {
		return this.iCount;
	}

	/**
	 * 当前运行的实例个数加一
	 */
	private synchronized void addCount() {
		this.iCount++;
	}

	/**
	 * 当前运行的实例个数减一
	 */
	private synchronized void reduceCount() {
		this.iCount--;
	}

	/**
	 * 加锁
	 */
	public void lock() throws RemoteException {
		mLock.lock();
	}

	/**
	 * 加锁
	 */
	public boolean trylock() throws RemoteException {
		return mLock.tryLock();
	}

	/**
	 * 解锁
	 */
	public void unlock() {
		mLock.unlock();
	}

}
